package link.chengguo.orangemall.service.jms.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import link.chengguo.orangemall.ApiContext;
import link.chengguo.orangemall.jms.entity.JmsPickingUser;
import link.chengguo.orangemall.jms.mapper.JmsPickingUserMapper;
import link.chengguo.orangemall.jms.service.IJmsPickingUserService;
import link.chengguo.orangemall.ums.service.RedisService;
import link.chengguo.orangemall.util.JsonUtils;
import link.chengguo.orangemall.util.JwtTokenUtil;
import link.chengguo.orangemall.utils.ValidatorUtils;
import link.chengguo.orangemall.vo.PickingUserDetails;
import link.chengguo.orangemall.vo.Rediskey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yzb
 * @date 2020-02-26
 */
@Service
public class JmsPickingUserServiceImpl extends ServiceImpl
        <JmsPickingUserMapper, JmsPickingUser> implements IJmsPickingUserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(JmsPickingUserServiceImpl.class);
    @Resource
    private JmsPickingUserMapper jmsPickingUserMapper;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;
    @Resource
    private RedisService redisService;
    @Autowired
    private ApiContext apiContext;
    @Resource
    private UserDetailsService userDetailsService;

    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Value("${redis.key.prefix.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${authCode.expire.seconds}")
    private Long AUTH_CODE_EXPIRE_SECONDS;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Value("${aliyun.sms.expire-minute:1}")
    private Integer expireMinute;

    @Override
    public JmsPickingUser getCurrentPickingUser() {
        try {
            JmsPickingUser user=null;
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            String requestType = request.getMethod();
            if ("OPTIONS".equals(requestType)) {
                return null;
            }
            String storeId = request.getParameter("storeid");
            if (ValidatorUtils.empty(storeId)) {
                storeId = request.getHeader("storeid");
            }
            if (storeId==null){
                storeId="1";
            }
            String tokenPre = "authorization" + storeId;
            String authHeader = request.getParameter(tokenPre);
            if (ValidatorUtils.empty(authHeader)) {
                authHeader = request.getHeader(tokenPre);
            }
            if (authHeader != null && authHeader.startsWith("Bearer")) {
                String authToken = authHeader.substring("Bearer".length());
                String username = jwtTokenUtil.getUserNameFromToken(authToken);
                if (ValidatorUtils.notEmpty(username)) {
                    user = JsonUtils.jsonToPojo(redisService.get(apiContext.getCurrentProviderId() + ":" + String.format(Rediskey.PICKING_USER, username)), JmsPickingUser.class);
                    if (user == null || user.getId() == null) {
                        user = getByPhone(username);
                    }
                    return user;
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return new JmsPickingUser();
        }
    }

    @Override
    public JmsPickingUser getByPhone(String phone) {
        return jmsPickingUserMapper.selectOne(new QueryWrapper<JmsPickingUser>().eq("phone",phone));
    }

    @Override
    public Object login(String phone, String pwd) {
        Map<String, Object> tokenMap = new HashMap<>();
        String token = null;
        PickingUserDetails userDetails = (PickingUserDetails) userDetailsService.loadUserByUsername("#picking#"+phone);
        if (userDetails==null){
            throw new RuntimeException("用户名不存在");
        }
        if (!passwordEncoder.matches(pwd, userDetails.getPassword())) {
            throw new RuntimeException("密码不正确");
        }
        JmsPickingUser member = this.getByPhone(phone);
        if (member.getStatus()==0){
            throw new RuntimeException("该账号已停用");
        }
        //   Authentication authentication = authenticationManager.authenticate(authenticationToken);
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        token = jwtTokenUtil.generateToken(userDetails);
        member.setPwd(null);
        tokenMap.put("userInfo", member);
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return tokenMap;
    }

    @Override
    public boolean updateUserInfo(JmsPickingUser user) {
        user.setPwd(null);
        user.setUpdateTime(new Date());
        return jmsPickingUserMapper.updateById(user)>0?true:false;
    }

    @Override
    public boolean updatePwd(JmsPickingUser user, String oldPwd, String newPwd) {
        if (!passwordEncoder.matches(oldPwd, user.getPwd())) {
            throw new RuntimeException("密码错误");
        }
        if (ValidatorUtils.isEmpty(newPwd)){
            throw new RuntimeException("新密码不能为空");
        }
        String md5Password = passwordEncoder.encode(newPwd);
        user.setPwd(md5Password);
        jmsPickingUserMapper.updateById(user);
        return true;
    }

}
